'''
=================
limber.ui.actions
=================

This module implements most of the Application actions.
It is used to keep quite clean the Application class.
'''

from limber.ui import tools as uitools


class ActionContainerError(Exception):pass


class Action(object):
    '''Describes an action to be created.'''
    
    __slots__ = (
            'parent',
            'text',
            'icon',
            'slot',
            'signal',
            'shortcut',
            'checkable',
            'status_tip',
            'tool_tip',
            'whats_this',
            'data',
            'propagate_tips',
            'has_data')
    
    def __init__(self, parent=None, text=None, icon=None,
                slot=None, signal='triggered()', shortcut=None,
                checkable=False, status_tip=None, tool_tip=None, whats_this=None,
                data=None, propagate_tips=True, has_data=False):
        self.parent = parent
        self.text = text
        self.icon = icon
        self.slot = slot
        self.signal = signal
        self.shortcut = shortcut
        self.checkable = checkable
        self.status_tip = status_tip
        self.tool_tip = tool_tip
        self.whats_this = whats_this
        self.data = data
        self.propagate_tips = propagate_tips
        self.has_data = self.has_data
    
    def __iter__(self):
        return (getattr(self, attr) for attr in self.__slots__)


class ActionContainer(object):
    '''The class that contains the actions of the application.'''
    
    def __init__(self, app):
        self._app = app
        self._actions = {}
        self._actions_to_setup = {}
        self._saved_actions = {}
    
    @property
    def app(self)
        '''The ActionContainer's Application object.'''
        
        return self._app
    
    def register_action(self, name, action):
        '''This method registers the *action* with *name*.'''
        
        if name in self._actions or name in self._actions_to_setup:
            raise ActionContainerError('There is an other action registered as %r'
                                        % name)
        self._actions_to_setup[name] = action
    
    def unregister_action(self, name):
        '''Unregisters the action called *name*.'''
        
        try:
            del self._actions_to_setup[name]
        except KeyError:
            raise ActionContainerError('There is no action registered as %r' % name)
    
    def setup_actions(self):
        '''Sets up the application actions.'''
        
        if self._app is None:
            raise ActionContainerError('Cannot setup without an application.')
        
        for name, action in self._actions_to_setup.iteritems():
            qaction = uitools.create_action(*action)
            self._app.add_action(name, qaction)
            self._actions[name] = qaction
        
        self._actions_to_setup = {}
    
    def clear_actions(self):
        '''Clears all actions setted up.'''
        
        if self._app is None:
            raise ActionContainerError('Cannot remove action without an application.')
        
        for qaction in self._actions.itervalues():
            self._app.remove_action(qaction)
        
        self._actions = {}
    
    def save_actions(self):
        '''Saves the actions currently registered.'''
        
        self._saved_actions.update(self._actions_to_setup)
    
    def forget_actions(self):
        '''Clears the saved actions.'''
        
        self._saved_actions = {}
    
    def resetup(self):
        '''Uses the previously saved actions to setup the application.'''
        
        for name, action in self._saved_actions.iteritems():
            qaction = uitools.create_action(*action)
            self._app.add_action(name, qaction)
            self._actions[name] = qaction